/*
 * @Author: mat
 * @Date: 2021-03-29 07:57:37
 * @LastEditTime: 2021-04-14 14:23:47
 * @Description: Cesium 相关工具方法，包含坐标转换、定位等
 */

let PI = 3.1415926535897932384626
let a = 6378245.0
let ee = 0.00669342162296594323

// 世界坐标转地理坐标
function cartesian3ToCartographic(cartesian3) {
	let car = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3)
	let lon = Cesium.Math.toDegrees(car.longitude)
	let lat = Cesium.Math.toDegrees(car.latitude)
	// console.log([lon, lat])
	return [lon, lat]
}

function toCartesian3(geoPoint) {
	let cartographic = Cesium.Cartographic.fromDegrees(geoPoint.lon, geoPoint.lat, geoPoint.alt);
	let cartesian3 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);
	return cartesian3;
}
// 屏幕坐标转地理坐标  cartesian2 -> cartesian3 -> 经纬度
function cartesian2ToCartographic(cartesian2) {
	let cartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(cartesian2), viewer.scene)
	return cartesian3ToCartographic(cartesian3)
}
// 计算弧度
function getRad(d) {
	let PI = Math.PI
	return (d * PI) / 180.0
}
// 计算两个经纬度之间的距离
function getDistance(position1, position2) {
	let f = getRad((position1[1] + position2[1]) / 2)
	let g = getRad((position1[1] - position2[1]) / 2)
	let l = getRad((position1[0] - position2[0]) / 2)
	let sg = Math.sin(g)
	let sl = Math.sin(l)
	let sf = Math.sin(f)
	let s
	let c
	let w
	let r
	let d
	let h1
	let h2
	let a = 6378137.0 // The Radius of eath in meter.
	let fl = 1 / 298.257
	sg = sg * sg
	sl = sl * sl
	sf = sf * sf
	s = sg * (1 - sl) + (1 - sf) * sl
	c = (1 - sg) * (1 - sl) + sf * sl
	w = Math.atan(Math.sqrt(s / c))
	r = Math.sqrt(s * c) / w
	d = 2 * w * a
	h1 = (3 * r - 1) / 2 / c
	h2 = (3 * r + 1) / 2 / s
	s = d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg))
	// s = s.toFixed(2);//指定小数点后的位数。
	return s
}
/**
 * @description: 定位
 * @param {}
 * @return {void}
 */
function flyto(lon, lat, height = 1000, duration = 3) {
	viewer.camera.flyTo({
		destination: Cesium.Cartesian3.fromDegrees(lon, lat, height),
		orientation: {
			// direction: new Cesium.Cartesian3(0.45904975240281715, -0.7716157298225791, -0.4403208946998551),
			// up: new Cesium.Cartesian3(0.3348182651807713, -0.30882279389790757, 0.8902388506858311)
		},
		duration: duration
	})
}
// 定位至矩形
function flyToRect(rect) {
	viewer.camera.flyTo({
		destination: Cesium.Rectangle.fromDegrees(rect[0], rect[1], rect[2], rect[3])
	})
}
/**
 * WGS84转GCj02
 */
function wgs84togcj02(lng, lat) {
	if (out_of_china(lng, lat)) {
		return [lng, lat]
	} else {
		let dlat = transformlat(lng - 105.0, lat - 35.0)
		let dlng = transformlng(lng - 105.0, lat - 35.0)
		let radlat = (lat / 180.0) * PI
		let magic = Math.sin(radlat)
		magic = 1 - ee * magic * magic
		let sqrtmagic = Math.sqrt(magic)
		dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI)
		dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI)
		let mglat = lat + dlat
		let mglng = lng + dlng
		return [mglng, mglat]
	}
}
/**
 * GCJ02 转换为 WGS84
 */
function gcj02towgs84(lng, lat) {
	if (out_of_china(lng, lat)) {
		return [lng, lat]
	} else {
		let dlat = transformlat(lng - 105.0, lat - 35.0)
		let dlng = transformlng(lng - 105.0, lat - 35.0)
		let radlat = (lat / 180.0) * PI
		let magic = Math.sin(radlat)
		magic = 1 - ee * magic * magic
		let sqrtmagic = Math.sqrt(magic)
		dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI)
		dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI)
		let mglat = lat + dlat
		let mglng = lng + dlng
		return [lng * 2 - mglng, lat * 2 - mglat]
	}
}
function transformlat(lng, lat) {
	let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
	ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
	ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0
	ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0
	return ret
}
function transformlng(lng, lat) {
	let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
	ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
	ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0
	ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0
	return ret
}
/**
 * 判断是否在国内，不在国内则不做偏移
 */
function out_of_china(lng, lat) {
	return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271 || false
}

// 获取高度对应层级
function getLevel(height) {
	if (height > 48000000) {
		return 0
	} else if (height > 24000000) {
		return 1
	} else if (height > 12000000) {
		return 2
	} else if (height > 6000000) {
		return 3
	} else if (height > 3000000) {
		return 4
	} else if (height > 1500000) {
		return 5
	} else if (height > 750000) {
		return 6
	} else if (height > 375000) {
		return 7
	} else if (height > 187500) {
		return 8
	} else if (height > 93750) {
		return 9
	} else if (height > 46875) {
		return 10
	} else if (height > 23437.5) {
		return 11
	} else if (height > 11718.75) {
		return 12
	} else if (height > 5859.38) {
		return 13
	} else if (height > 2929.69) {
		return 14
	} else if (height > 1464.84) {
		return 15
	} else if (height > 732.42) {
		return 16
	} else if (height > 366.21) {
		return 17
	} else {
		return 18
	}
}

// 计算中心点坐标
function culCenter(posArr) {
	let lonA = 0
	let latA = 0
	for (let i in posArr) {
		if (i % 2) {
			latA = latA + posArr[i]
		} else {
			lonA = lonA + posArr[i]
		}
	}
	return [lonA / (posArr.length / 2), latA / (posArr.length / 2)]
}
function formatDegree(value) {
	// /<summary>将度转换成为度分秒</summary>

	value = Math.abs(value)
	var v1 = Math.floor(value) // 度
	var v2 = Math.floor((value - v1) * 60) // 分
	var v3 = Math.round(((value - v1) * 3600) % 60) // 秒
	return v1 + '°' + v2 + '′' + v3 + '″'
}

function DegreeConvertBack(value) {
	// /<summary>度分秒转换成为度</summary>
	var du = value.split('°')[0]
	var fen = value.split('°')[1].split('′')[0]
	var miao = value
		.split('°')[1]
		.split('′')[1]
		.split('″')[0]

	return Math.abs(du) + (Math.abs(fen) / 60 + Math.abs(miao) / 3600)
}

export { cartesian3ToCartographic, toCartesian3, cartesian2ToCartographic, getRad, getDistance, flyto, flyToRect, wgs84togcj02, gcj02towgs84, getLevel, culCenter, formatDegree, DegreeConvertBack }
